#ifndef CHESSBOARD_H
#define CHESSBOARD_H

#include "ChessType.h"
#include "ChessManMoveTable.h"
#include <iostream>
#include <cmath>
#include <queue>
#include <stack>

#include "Logger.h"

class ChessBoard
{
public:
	ChessBoard(void);
	~ChessBoard(void);

	//reset all of the board's state
	void			Reset();

	//decide if a move is legal
	bool			LegalMove(const ChessManMoveInfo& info) const;

	//find the current player's all legal move,push it into the infoQueue
	void FindAllLegalMove(std::queue<ChessManMoveInfo>& infoQueue,int _playerType) const;

	//move a chessman,return false if the move is illegal
	//ps: the info.step must be positive
	bool			MoveChessMan(const ChessManMoveInfo& info);

	//reset the plater's control scope
	//void			ResetCtrlScope();

	//if set true,it will update the board update info
	//when calculate the AI ,it could set false to get efficiency improve
	void			EnableBoardUpdateInfo(bool enable);

	//get the ChessMan's type in one grid
	int				GetChessManType(const BoardCoord& coord) const;

	//retract one move,return true if success
	//bool			RetractOneMove();
public:
	short			m_Board[ChessBoardSize][ChessBoardSize];
	//bool			m_WhiteCtrlScope[ChessBoardSize][ChessBoardSize];
	//bool			m_BlackCtrlScope[ChessBoardSize][ChessBoardSize];

	int				m_CurrPlayer;

	CastleState		m_BlackKingSide;
	CastleState		m_BlackQueenSide;
	CastleState		m_WhiteKingSide;
	CastleState		m_WhiteQueenSide;

	//when a pawn move 2 step from it's origin , it can be en passant captured
	bool			m_bCanEnPassant;

	bool			m_bGameOver;

	int				m_Winner;
	//the coordinate 0<=x,y<8
	BoardCoord		m_EnPassant;

	//the board update info tell the scene manager how to manipulate the scene node
	ChessBoardUpdateInfo m_ChessBoardUpdateInfo;

	//static std::string m_debugStr;

private:
	//std::stack<ChessBoardUpdateInfo>	m_MoveInfoStack;

private:

	void	ResetBoard();
	void	ResetBoardState();

	//it determine if a move can cause a capture,but it doesn't guarantee
	//this move is legal
	bool CanCapture(const ChessManMoveInfo& info) const;

	//determine if a move has a legal direction
	bool HasLegalDir(const ChessManMoveInfo& info) const;

	//determine if a move can En Passant
	bool CanEnPassant(const ChessManMoveInfo& info) const;

	//determine if this move can castle
	bool CanCastle(const ChessManMoveInfo& info) const;

	//detect the out of chessboard and the obstructed,return false if nothing has be detected
	bool DetectOverstepAndObstructed(const ChessManMoveInfo& info) const;

	//update move information
	void UpdateMoveInfo(const ChessManMoveInfo& info,const BoardCoord& source,const BoardCoord& dest);

	//castle,move rook
	void MoveRook(const ChessManMoveInfo& info);
	//void RetractMoveRook(const ChessBoardUpdateInfo& info);

	inline void SetCastleState(const ChessManMoveInfo& info);

public:
	friend std::ostream& operator<<(std::ostream& os,const ChessBoard& board)
	{
		for(int i=RowBeginIndex;i<RowBeginIndex+8;++i)
		{
			for(int j=ColBeginIndex;j<ColBeginIndex+8;++j)
			{
				os<<board.m_Board[i][j]<<" ";
			}
			os<<std::endl;
		}
		return os;
	}

};


#endif